﻿using BLL;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Utility;

namespace HealthCommissionShow
{
    public partial class MainForm : Form
    {

        private HttpListener m_Listener;  //Http侦听者  
        private static Thread m_Receivethread = null; //接收消息线程
        private string m_ListerURL = ""; //Http监听地址

        public MainForm()
        {
            InitializeComponent();
        }


        /// <summary>
        ///  窗体加载事件回调函数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MainForm_Load(object sender, EventArgs e)
        {
            sm = ShowHttpMessage; //给委托变量赋目标方法
            //启动Http监听
            HttpLister();
      
        }

        #region HTTP

        /// <summary>
        /// 启动http监听
        /// </summary>
        private void HttpLister()
        {
            m_ListerURL = AppConfig.HttpListenerApp;//IP地址
            if (m_Listener == null) //初始化HTTP 协议侦听器
            {
                m_Listener = new HttpListener();
                m_Listener.AuthenticationSchemes = AuthenticationSchemes.Anonymous; //指定匿名身份验证
                m_Listener.Prefixes.Add(m_ListerURL); //添加监听地址
            }
            if (m_Receivethread == null) //启动监听线程
            {
                m_Receivethread = new Thread(new ThreadStart(ThreadStartProc));
                m_Receivethread.IsBackground = true; //设置线程为后台线程，不会阻止进程结束
                m_Receivethread.Start();//启动线程
            }
        }


        /// <summary>
        /// Http监听线程
        /// </summary>
        private void ThreadStartProc()
        {
            try
            {
                m_Listener.Start(); //允许此实例接收传入的请求---开始在监听地址侦听Http协议
                ThreadShowMsg(AnchorEnum.EMessageLevel.EML_INFO, "开始在" + m_ListerURL + "侦听成功！");
            }
            catch (Exception ex)
            {
                ThreadShowMsg(AnchorEnum.EMessageLevel.EML_INFO, "在" + m_ListerURL + "侦听失败！原因：" + ex.Message);
                return;
            }

            while (true) //无限循环
            {
                HttpListenerContext context; //表示客户端请求的 System.Net.HttpListenerContext 对象
                try
                {
                    context = m_Listener.GetContext(); //等待传入的请求，接收到请求时返回
                }
                catch (Exception ex)
                {
                    LogUtility.Error("MainForm/ThreadStartProc()", "收到数据异常：" + ex.Message);
                    ThreadShowMsg(AnchorEnum.EMessageLevel.EML_ERROR, "收到数据异常：" + ex.Message);
                    continue;
                }

                if (context.Request.HasEntityBody) //如果该请求有关联的正文数据过来   
                    DealClientData(context.Request, context.Response); //创建线程处理接收到的数据
            }
        }

        /// <summary>
        /// 启动线程处理客户端的HTTP请求数据
        /// </summary>
        /// <param name="httpListenerRequest"></param>
        /// <param name="httpListenerResponse"></param>
        private void DealClientData(HttpListenerRequest request, HttpListenerResponse response)
        {
            DealHttpDataBLL dpBll = new DealHttpDataBLL(request, response); //根据传入的HTTP请求和正在处理的响应实例化DealHttpDataBLL类
            Thread ClientThread = new Thread(new ThreadStart(dpBll.ReceiveHttpData));//初始化一个线程---接收hhtp请求消息处理
            dpBll.ShowMessage += new DealHttpDataBLL.ShowMessageHandler(ShowHttpMessage);//目标方法赋值给委托
            ClientThread.IsBackground = true;//设置线程为后台线程，不会阻止进程结束
            ClientThread.Start();//启动线程
        }

        #endregion




        #region  ListView消息显示

        /// <summary>
        /// 显示http请求消息
        /// </summary>
        /// <param name="messageLevel"></param>
        /// <param name="message"></param>
        private void ShowHttpMessage(AnchorEnum.EMessageLevel messageLevel, string message)
        {
            ShowListViewMessage(listView, messageLevel, message);
        }

        /// <summary>
        /// ListView中添加新项
        /// </summary>
        /// <param name="lv"></param>
        /// <param name="messageLevel"></param>
        /// <param name="message"></param>
        private void ShowListViewMessage(ListView lv, AnchorEnum.EMessageLevel messageLevel, string message)
        {
            if (lv.Items.Count > 1000)
                lv.Items.Clear(); //从集合中移除所有项

            ListViewItem lvItem = new ListViewItem();
            lvItem.ImageIndex = (int)messageLevel;
            lvItem.Text = "";

            ListViewItem.ListViewSubItem lvsItem = new ListViewItem.ListViewSubItem();
            lvsItem.Text = DateTime.Now.ToString(); //时间
            lvItem.SubItems.Add(lvsItem);

            lvsItem = new ListViewItem.ListViewSubItem();
            lvsItem.Text = message; //消息内容
            lvItem.SubItems.Add(lvsItem);

            //lv.Items.Add(lvItem);//在最后一行插 
            lv.Items.Insert(0, lvItem);//在第一行插
        }

        #endregion


        #region 主窗体关闭事件回调

        /// <summary>
        /// 使用进程管理器关闭程序时不会触发，因为这里的事件只能处理内部消息，无法处理来自外部消息
        /// 窗体程序关闭前回调函数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (MessageBox.Show("确定退出系统吗？", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.No)
            {
                e.Cancel = true;
            }
            else
            {
                this.Dispose();
            }
        }

        /// <summary>
        /// 窗体程序关闭后回调函数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            this.Close(); //this指代当前窗体对象 
            LogUtility.Debug("FormMain_FormClosed", "程序退出");
        }

        #endregion


        #region 委托

        /// <summary>
        /// 显示消息委托
        /// </summary>
        /// <param name="content"></param>
        private delegate void ShowMsgDelegate(AnchorEnum.EMessageLevel messageLevel, string message);

        private ShowMsgDelegate sm;

        private void ThreadShowMsg(AnchorEnum.EMessageLevel messageLevel, string message)
        {
            this.Invoke(sm, new object[] { messageLevel, message });
        }

        #endregion


    }
}
